<!DOCTYPE html>

<html lang="zh-CN">

<head>
    
    <title>练习之RBAC简单权限 - 塔纳托斯</title>
    <meta charset="UTF-8">
    <meta name="keywords" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5">
    
    

    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
    <meta name="description" content="RBAC，Role-Based Access Control，基于角色的访问控制 RBAC模型的核心是在用户和权限之间引入了角色的概念，取消了用户和权限的直接关联，改为通过用户关联角色、角色关联权限的方法来间接地赋予用户权限，从而达到用户和权限解耦的目的 本次练习粗略的实现基于RBAC的简单权限系统 表设计总共5张表，分别为user，role，user_role，permission，role_p">
<meta property="og:type" content="article">
<meta property="og:title" content="练习之RBAC简单权限">
<meta property="og:url" content="http://hai-chao.gitee.io/blog/2022/01/15/24.lian-xi-zhi-rbac-jian-dan-quan-xian/index.html">
<meta property="og:site_name" content="塔纳托斯">
<meta property="og:description" content="RBAC，Role-Based Access Control，基于角色的访问控制 RBAC模型的核心是在用户和权限之间引入了角色的概念，取消了用户和权限的直接关联，改为通过用户关联角色、角色关联权限的方法来间接地赋予用户权限，从而达到用户和权限解耦的目的 本次练习粗略的实现基于RBAC的简单权限系统 表设计总共5张表，分别为user，role，user_role，permission，role_p">
<meta property="og:locale" content="zh_CN">
<meta property="article:published_time" content="2022-01-15T10:00:00.000Z">
<meta property="article:modified_time" content="2022-01-16T08:11:17.841Z">
<meta property="article:author" content="塔纳托斯">
<meta property="article:tag" content="学习">
<meta name="twitter:card" content="summary">
    <link rel="stylesheet" href="/blog/lib/jquery.fancybox.min.css?v=1679297521103">
    
    <link rel="stylesheet" href="/blog/lib/mdui_043tiny/css/mdui.css?v=1679297521103">
    <link rel="stylesheet" href="/blog/lib/iconfont/iconfont.css?v=1679297521103">
    <link rel="stylesheet" href="/blog/css/style.css?v=1679297521103">
     
    
<meta name="generator" content="Hexo 5.3.0"><link rel="alternate" href="/blog/atom.xml" title="塔纳托斯" type="application/atom+xml">
<link rel="stylesheet" href="/blog/css/prism-tomorrow.css" type="text/css"></head>

<body class="mdui-drawer-body-left">
    
    <div id="nexmoe-background">
        <div class="nexmoe-bg" style="background-image: url(https://cdn.jsdelivr.net/gh/nexmoe/nexmoe.github.io@latest/images/cover/5c3aec85a4343.jpg)"></div>
        <div class="mdui-appbar mdui-shadow-0">
            <div class="mdui-toolbar">
                <a mdui-drawer="{target: '#drawer', swipe: true}" title="menu" class="mdui-btn mdui-btn-icon mdui-ripple"><i class="mdui-icon nexmoefont icon-menu"></i></a>
                <div class="mdui-toolbar-spacer"></div>
                <!--<a href="javascript:;" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">search</i></a>-->
                <a href="/blog/" title="塔纳托斯" class="mdui-btn mdui-btn-icon"><img src="https://s6.jpg.cm/2022/01/17/LFpniO.md.jpg" alt="塔纳托斯"></a>
            </div>
        </div>
    </div>
    <div id="nexmoe-header">
        <div class="nexmoe-drawer mdui-drawer" id="drawer">
    <div class="nexmoe-avatar mdui-ripple">
        <a href="/blog/" title="塔纳托斯">
            <img src="https://s6.jpg.cm/2022/01/17/LFpniO.md.jpg" alt="塔纳托斯" alt="塔纳托斯">
        </a>
    </div>
    <div class="nexmoe-count">
        <div><span>文章</span>29</div>
        <div><span>标签</span>6</div>
        <div><span>分类</span>0</div>
    </div>
    <div class="nexmoe-list mdui-list" mdui-collapse="{accordion: true}">
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple false" href="/blog/" title="文章归档">
            <i class="mdui-list-item-icon nexmoefont icon-container"></i>
            <div class="mdui-list-item-content">
                文章归档
            </div>
        </a>
        
    </div>
    <aside id="nexmoe-sidebar">
    
    
  <div class="nexmoe-widget-wrap">
    <div id="randomtagcloud" class="nexmoe-widget tagcloud nexmoe-rainbow">
      <a href="/blog/tags/java/" style="font-size: 10px;">java</a> <a href="/blog/tags/%E5%88%86%E4%BA%AB/" style="font-size: 20px;">分享</a> <a href="/blog/tags/%E5%90%83%E7%93%9C/" style="font-size: 10px;">吃瓜</a> <a href="/blog/tags/%E5%AD%A6%E4%B9%A0/" style="font-size: 16.67px;">学习</a> <a href="/blog/tags/%E6%80%BB%E7%BB%93/" style="font-size: 13.33px;">总结</a> <a href="/blog/tags/%E6%B8%B8%E5%90%8E%E6%84%9F/" style="font-size: 10px;">游后感</a>
    </div>
    
  </div>

    
</aside>
    <div class="nexmoe-copyright">
        &copy; 2023 塔纳托斯
        Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
        & <a href="https://github.com/theme-nexmoe/hexo-theme-nexmoe" target="_blank">Nexmoe</a>
        
    </div>
</div><!-- .nexmoe-drawer -->
    </div>
    <div id="nexmoe-content">
        <div class="nexmoe-primary">
            <div class="nexmoe-post">

  <article>
      
          <div class="nexmoe-post-cover"> 
              
              <h1>练习之RBAC简单权限</h1>
          </div>
      
      
      <div class="nexmoe-post-meta nexmoe-rainbow" style="margin:10px 0!important;">
    <a><i class="nexmoefont icon-calendar-fill"></i>2022年01月15日</a>
</div>

      

      <p>RBAC，Role-Based Access Control，基于角色的访问控制</p>
<p>RBAC模型的核心是在用户和权限之间引入了角色的概念，取消了用户和权限的直接关联，改为<strong>通过用户关联角色、角色关联权限的方法来间接地赋予用户权限</strong>，从而达到用户和权限解耦的目的</p>
<p>本次练习<strong>粗略的实现</strong>基于RBAC的简单权限系统</p>
<h2 id="表设计"><a href="#表设计" class="headerlink" title="表设计"></a>表设计</h2><p>总共5张表，分别为user，role，user_role，permission，role_permission</p>
<p>user字段为：id，username，password</p>
<p>role字段为：id，role_name</p>
<p>user_role字段为：uid，rid（联合主键）</p>
<p>permission字段为：id，permission_name</p>
<p>role_permission字段为：rid，pid（联合主键）</p>
<p>其中role表数据为：</p>
<table>
<thead>
<tr>
<th>id</th>
<th>role_name</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>admin</td>
</tr>
<tr>
<td>2</td>
<td>common</td>
</tr>
</tbody></table>
<p>permission表数据为：</p>
<table>
<thead>
<tr>
<th>id</th>
<th>permission_name</th>
</tr>
</thead>
<tbody><tr>
<td>1</td>
<td>user:query</td>
</tr>
<tr>
<td>2</td>
<td>user:insert</td>
</tr>
<tr>
<td>3</td>
<td>user:delete</td>
</tr>
<tr>
<td>4</td>
<td>user:update</td>
</tr>
</tbody></table>
<p>然后是admin有所有权限，common有user:query权限</p>
<h2 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h2><h3 id="项目结构"><a href="#项目结构" class="headerlink" title="项目结构"></a>项目结构</h3><p>采用spring boot实现，刚开始包结构为po，mapper，service，controller，utils</p>
<p>要实现的需求为：用户登录的过程中进行认证、授权，使用功能进行鉴权</p>
<h3 id="封装响应类"><a href="#封装响应类" class="headerlink" title="封装响应类"></a>封装响应类</h3><p>在utils包下封装响应类，一个是状态码的枚举，一个是BaseResponse类（我简写成R）</p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">enum</span> RespCode <span class="token punctuation">{</span>
    <span class="token function">Success</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">"成功"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token function">Fail</span><span class="token punctuation">(</span><span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token string">"失败"</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">;</span>

    <span class="token keyword">private</span> Integer code<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String msg<span class="token punctuation">;</span>

    <span class="token function">RespCode</span><span class="token punctuation">(</span>Integer code<span class="token punctuation">,</span> String msg<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> code<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>msg <span class="token operator">=</span> msg<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> Integer <span class="token function">getCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCode</span><span class="token punctuation">(</span>Integer code<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> String <span class="token function">getMsg</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> msg<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMsg</span><span class="token punctuation">(</span>String msg<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>msg <span class="token operator">=</span> msg<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">R</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> Integer code<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String msg<span class="token punctuation">;</span>
    <span class="token keyword">private</span> List data<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token function">R</span><span class="token punctuation">(</span>RespCode respCode<span class="token punctuation">,</span>List data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> respCode<span class="token punctuation">.</span><span class="token function">getCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>msg <span class="token operator">=</span> respCode<span class="token punctuation">.</span><span class="token function">getMsg</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> data<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> R <span class="token function">out</span><span class="token punctuation">(</span>RespCode respCode<span class="token punctuation">,</span>List data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">R</span><span class="token punctuation">(</span>respCode<span class="token punctuation">,</span>data<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> Integer <span class="token function">getCode</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setCode</span><span class="token punctuation">(</span>Integer code<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>code <span class="token operator">=</span> code<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> String <span class="token function">getMsg</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> msg<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setMsg</span><span class="token punctuation">(</span>String msg<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>msg <span class="token operator">=</span> msg<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> List <span class="token function">getData</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">return</span> data<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">setData</span><span class="token punctuation">(</span>List data<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>data <span class="token operator">=</span> data<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="认证"><a href="#认证" class="headerlink" title="认证"></a>认证</h3><p><strong>认证，Identification</strong>：根据声明者持有的特定信息，来确认声明者的身份</p>
<p>在LoginController中</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Controller</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginController</span> <span class="token punctuation">{</span>

    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"/login"</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> R <span class="token function">login</span><span class="token punctuation">(</span>HttpSession session<span class="token punctuation">,</span> User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        String username <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        String password <span class="token operator">=</span> user<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>StringUtils<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">UserNameIsEmptyException</span><span class="token punctuation">(</span><span class="token string">"用户名为空"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        User needUser <span class="token operator">=</span> userService<span class="token punctuation">.</span><span class="token function">findUserByName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">if</span><span class="token punctuation">(</span>needUser <span class="token operator">==</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">UserNotFindException</span><span class="token punctuation">(</span><span class="token string">"用户没有找到"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span>needUser<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>password<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PasswordIsNotCorrectException</span><span class="token punctuation">(</span><span class="token string">"密码错误"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token comment" spellcheck="true">//认证结束后，将username存入到session中</span>
        session<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">,</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token keyword">return</span> R<span class="token punctuation">.</span><span class="token function">out</span><span class="token punctuation">(</span>RespCode<span class="token punctuation">.</span>Success<span class="token punctuation">,</span>null<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="授权"><a href="#授权" class="headerlink" title="授权"></a>授权</h3><p><strong>授权，Authorization</strong>：简单来说，资源所有者给予执行者权限</p>
<p>在这个练习中，授权就是在认证结束后，查询角色后存入到session中，查询权限存入到session中</p>
<pre class=" language-java"><code class="language-java"><span class="token comment" spellcheck="true">//在login方法中认证结束后进行授权</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"/login"</span><span class="token punctuation">)</span>
<span class="token annotation punctuation">@ResponseBody</span>
<span class="token keyword">public</span> R <span class="token function">login</span><span class="token punctuation">(</span>HttpSession session<span class="token punctuation">,</span> User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//  ......</span>
    <span class="token comment" spellcheck="true">//认证结束后，将username存入到session中</span>
    session<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">,</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token comment" spellcheck="true">//授权</span>
    List<span class="token operator">&lt;</span>Role<span class="token operator">></span> roles <span class="token operator">=</span> roleService<span class="token punctuation">.</span><span class="token function">getRolesByUserName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
    List<span class="token operator">&lt;</span>Permission<span class="token operator">></span> permissions <span class="token operator">=</span> permissionService<span class="token punctuation">.</span><span class="token function">getPermissionsByUserName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

    List<span class="token operator">&lt;</span>String<span class="token operator">></span> roleStr <span class="token operator">=</span> roles<span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Role<span class="token operator">:</span><span class="token operator">:</span>getRole_name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>Collectors<span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    List<span class="token operator">&lt;</span>String<span class="token operator">></span> permissionStr <span class="token operator">=</span> permissions<span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Permission<span class="token operator">:</span><span class="token operator">:</span>getPermission_name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>Collectors<span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

    session<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"roles"</span><span class="token punctuation">,</span>roleStr<span class="token punctuation">)</span><span class="token punctuation">;</span>
    session<span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"permissions"</span><span class="token punctuation">,</span>permissionStr<span class="token punctuation">)</span><span class="token punctuation">;</span>

    <span class="token keyword">return</span> R<span class="token punctuation">.</span><span class="token function">out</span><span class="token punctuation">(</span>RespCode<span class="token punctuation">.</span>Success<span class="token punctuation">,</span>null<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>关于list.stream().map()是java8的新特性，按我目前理解是将对象的属性提取出来后再存入到list中，以后有时间重点详解一下这个API</p>
<h3 id="鉴权"><a href="#鉴权" class="headerlink" title="鉴权"></a>鉴权</h3><p><strong>鉴权，Authentication</strong>：对声明者的权限进行鉴别</p>
<p>在本次练习中，使用aop来实现鉴权</p>
<p>在UserController中，我想对增加用户做权限限制</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Controller</span>
<span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"/user"</span><span class="token punctuation">)</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserController</span> <span class="token punctuation">{</span>

    <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"/addUser"</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token annotation punctuation">@HasPermission</span><span class="token punctuation">(</span><span class="token string">"user:add"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> R <span class="token function">addUser</span><span class="token punctuation">(</span>HttpSession session<span class="token punctuation">,</span>User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        userService<span class="token punctuation">.</span><span class="token function">insertUser</span><span class="token punctuation">(</span>user<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> R<span class="token punctuation">.</span><span class="token function">out</span><span class="token punctuation">(</span>RespCode<span class="token punctuation">.</span>Success<span class="token punctuation">,</span>null<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>创建自定义注解@HasPermission</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Target</span><span class="token punctuation">(</span>ElementType<span class="token punctuation">.</span>METHOD<span class="token punctuation">)</span>
<span class="token annotation punctuation">@Retention</span><span class="token punctuation">(</span>RetentionPolicy<span class="token punctuation">.</span>RUNTIME<span class="token punctuation">)</span>
<span class="token keyword">public</span> @<span class="token keyword">interface</span> <span class="token class-name">HasPermission</span> <span class="token punctuation">{</span>
    String <span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>创建切面PermissionAop</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Aspect</span>
<span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PermissionAop</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">//环绕通知</span>
    <span class="token annotation punctuation">@Around</span><span class="token punctuation">(</span><span class="token string">"@annotation(com.haichao.core.annotation.HasPermission)"</span><span class="token punctuation">)</span>
    <span class="token keyword">public</span> Object <span class="token function">around</span><span class="token punctuation">(</span>ProceedingJoinPoint joinPoint<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">//在切面中获取session</span>
        ServletRequestAttributes sra <span class="token operator">=</span> <span class="token punctuation">(</span>ServletRequestAttributes<span class="token punctuation">)</span> RequestContextHolder<span class="token punctuation">.</span><span class="token function">getRequestAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        HttpSession session <span class="token operator">=</span> sra<span class="token punctuation">.</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment" spellcheck="true">//拿到权限</span>
        List<span class="token operator">&lt;</span>String<span class="token operator">></span> permissions <span class="token operator">=</span> <span class="token punctuation">(</span>List<span class="token operator">&lt;</span>String<span class="token operator">></span><span class="token punctuation">)</span> session<span class="token punctuation">.</span><span class="token function">getAttribute</span><span class="token punctuation">(</span><span class="token string">"permissions"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token comment" spellcheck="true">//获取切入点注解的值</span>
        <span class="token comment" spellcheck="true">//joinPoint getTarget是获取类, getSignature是获取签名然后转成方法签名</span>
        HasPermission annotation <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>MethodSignature<span class="token punctuation">)</span> joinPoint<span class="token punctuation">.</span><span class="token function">getSignature</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getAnnotation</span><span class="token punctuation">(</span>HasPermission<span class="token punctuation">.</span><span class="token keyword">class</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        String needPermission <span class="token operator">=</span> annotation<span class="token punctuation">.</span><span class="token function">value</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment" spellcheck="true">//鉴权</span>
        <span class="token keyword">boolean</span> contains <span class="token operator">=</span> permissions<span class="token punctuation">.</span><span class="token function">contains</span><span class="token punctuation">(</span>needPermission<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>contains<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">NotHasPermissionException</span><span class="token punctuation">(</span><span class="token string">"没有权限"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token comment" spellcheck="true">//调用原有方法</span>
        Object returnObj <span class="token operator">=</span> null<span class="token punctuation">;</span>

        <span class="token keyword">try</span> <span class="token punctuation">{</span>
            returnObj <span class="token operator">=</span> joinPoint<span class="token punctuation">.</span><span class="token function">proceed</span><span class="token punctuation">(</span>joinPoint<span class="token punctuation">.</span><span class="token function">getArgs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Throwable</span> throwable<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            throwable<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>

        <span class="token keyword">return</span> returnObj<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="抽离认证和授权"><a href="#抽离认证和授权" class="headerlink" title="抽离认证和授权"></a>抽离认证和授权</h3><p>认证和授权都放在login方法中，当我们想在下个项目中使用这套权限管理时会显得不便，那我们是否可以将其抽离出来，形成类似于框架那种效果</p>
<p>为此在本次练习中创建core包用于放权限管理的核心代码</p>
<ol>
<li>首先将自定义注解、切面、自定义异常放入core包中</li>
<li>始终要明确core包中的内容不能调用外部资源，而外部用户是可以使用core包中的东西（类似于框架是不能调用使用者编写的代码，而使用者是利用框架来带来便利）</li>
</ol>
<p>在core包中创建一个类<strong>Subject</strong>，充当主体</p>
<p>因为不能够调用外部资源，po包中的类需要另外创建，因此创建了一个<strong>token</strong>和一个<strong>info</strong></p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserNameAndPasswordToken</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> String username<span class="token punctuation">;</span>
    <span class="token keyword">private</span> String password<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token function">UserNameAndPasswordToken</span><span class="token punctuation">(</span>String username<span class="token punctuation">,</span> String password<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>username <span class="token operator">=</span> username<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>password <span class="token operator">=</span> password<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">// getter and setter</span>
<span class="token punctuation">}</span></code></pre>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">PermissionInfo</span> <span class="token punctuation">{</span>
    <span class="token keyword">private</span> List<span class="token operator">&lt;</span>String<span class="token operator">></span> roles<span class="token punctuation">;</span>
    <span class="token keyword">private</span> List<span class="token operator">&lt;</span>String<span class="token operator">></span> permissions<span class="token punctuation">;</span>

    <span class="token keyword">public</span> <span class="token function">PermissionInfo</span><span class="token punctuation">(</span>List<span class="token operator">&lt;</span>String<span class="token operator">></span> roles<span class="token punctuation">,</span> List<span class="token operator">&lt;</span>String<span class="token operator">></span> permissions<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>roles <span class="token operator">=</span> roles<span class="token punctuation">;</span>
        <span class="token keyword">this</span><span class="token punctuation">.</span>permissions <span class="token operator">=</span> permissions<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token function">PermissionInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token punctuation">}</span>

    <span class="token comment" spellcheck="true">//getter and setter</span>
<span class="token punctuation">}</span></code></pre>
<p>然后开始抽离，这时会遇到问题，既然core包中的类不能调用外部资源，那么怎么调用各种service类是个问题，为此，需要在core包中创建一个接口，该接口的作用是让使用者来实现这个接口，让使用者来调用自己创建的各种service</p>
<p>创建Realm接口</p>
<pre class=" language-java"><code class="language-java"><span class="token keyword">public</span> <span class="token keyword">interface</span> <span class="token class-name">Realm</span> <span class="token punctuation">{</span>
    <span class="token comment" spellcheck="true">// 认证</span>
    UserNameAndPasswordToken <span class="token function">identification</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">;</span>
    <span class="token comment" spellcheck="true">// 授权</span>
    PermissionInfo <span class="token function">authorization</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">;</span>
<span class="token punctuation">}</span></code></pre>
<p>完善Subject</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Subject</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> Realm realm<span class="token punctuation">;</span>
    <span class="token keyword">private</span> <span class="token keyword">static</span> Realm myRealm<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@PostConstruct</span>
    <span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">init</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        myRealm <span class="token operator">=</span> realm<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">login</span><span class="token punctuation">(</span>String name<span class="token punctuation">,</span>String pwd<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token comment" spellcheck="true">// 认证</span>
        UserNameAndPasswordToken token <span class="token operator">=</span> myRealm<span class="token punctuation">.</span><span class="token function">identification</span><span class="token punctuation">(</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>
        String username <span class="token operator">=</span> token<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span><span class="token punctuation">(</span><span class="token operator">!</span>token<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">equals</span><span class="token punctuation">(</span>pwd<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">PasswordIsNotCorrectException</span><span class="token punctuation">(</span><span class="token string">"密码错误"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"username"</span><span class="token punctuation">,</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

        <span class="token comment" spellcheck="true">// 授权</span>
        <span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"roles"</span><span class="token punctuation">,</span>myRealm<span class="token punctuation">.</span><span class="token function">authorization</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getRoles</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">setAttribute</span><span class="token punctuation">(</span><span class="token string">"permissions"</span><span class="token punctuation">,</span>myRealm<span class="token punctuation">.</span><span class="token function">authorize</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getPermissions</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">public</span> <span class="token keyword">static</span> HttpSession <span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
        ServletRequestAttributes sra <span class="token operator">=</span> <span class="token punctuation">(</span>ServletRequestAttributes<span class="token punctuation">)</span> RequestContextHolder<span class="token punctuation">.</span><span class="token function">getRequestAttributes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> sra<span class="token punctuation">.</span><span class="token function">getRequest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>认证和授权的抽离基本结束</p>
<p>解释一下：因为login方法是static，因此无法使用realm变量，需要一个静态变量，因此创建静态变量myRealm，而myRealm无法注入，需要一些其他方法的帮助，为此写了init方法，而@PostConstruct注解的作用是：当Subject类注入到容器结束时，调用有该注解的方法。这样myRealm通过init方法将会有值</p>
<h3 id="实现Realm接口"><a href="#实现Realm接口" class="headerlink" title="实现Realm接口"></a>实现Realm接口</h3><p>在正式使用core中的内容时，要先实现Realm接口</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Component</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">UserRealm</span> <span class="token keyword">implements</span> <span class="token class-name">Realm</span> <span class="token punctuation">{</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> UserService userService<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> RoleService roleService<span class="token punctuation">;</span>
    <span class="token annotation punctuation">@Autowired</span>
    <span class="token keyword">private</span> PermissionService permissionService<span class="token punctuation">;</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> UserNameAndPasswordToken <span class="token function">identification</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>StringUtils<span class="token punctuation">.</span><span class="token function">isEmpty</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">UserNameIsEmptyException</span><span class="token punctuation">(</span><span class="token string">"用户名为空"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        User user <span class="token operator">=</span> userService<span class="token punctuation">.</span><span class="token function">findUserByName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">if</span> <span class="token punctuation">(</span>user <span class="token operator">==</span> null<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token class-name">UserNotFindException</span><span class="token punctuation">(</span><span class="token string">"用户没用找到"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">UserNameAndPasswordToken</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>user<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>

    <span class="token annotation punctuation">@Override</span>
    <span class="token keyword">public</span> PermissionInfo <span class="token function">authorization</span><span class="token punctuation">(</span>String username<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        List<span class="token operator">&lt;</span>Role<span class="token operator">></span> roles <span class="token operator">=</span> roleService<span class="token punctuation">.</span><span class="token function">getRolesByUserName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>
        List<span class="token operator">&lt;</span>Permission<span class="token operator">></span> permissions <span class="token operator">=</span> permissionService<span class="token punctuation">.</span><span class="token function">getPermissionsByUserName</span><span class="token punctuation">(</span>username<span class="token punctuation">)</span><span class="token punctuation">;</span>

        List<span class="token operator">&lt;</span>String<span class="token operator">></span> roleStr <span class="token operator">=</span> roles<span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Role<span class="token operator">:</span><span class="token operator">:</span>getRole_name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>Collectors<span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        List<span class="token operator">&lt;</span>String<span class="token operator">></span> permissionStr <span class="token operator">=</span> permissions<span class="token punctuation">.</span><span class="token function">stream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">map</span><span class="token punctuation">(</span>Permission<span class="token operator">:</span><span class="token operator">:</span>getPermission_name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">collect</span><span class="token punctuation">(</span>Collectors<span class="token punctuation">.</span><span class="token function">toList</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>

        PermissionInfo permissionInfo <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">PermissionInfo</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        permissionInfo<span class="token punctuation">.</span><span class="token function">setRoles</span><span class="token punctuation">(</span>roleStr<span class="token punctuation">)</span><span class="token punctuation">;</span>
        permissionInfo<span class="token punctuation">.</span><span class="token function">setPermissions</span><span class="token punctuation">(</span>permissionStr<span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token keyword">return</span> permissionInfo<span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<p>最后在LoginController中的调用方法</p>
<pre class=" language-java"><code class="language-java"><span class="token annotation punctuation">@Controller</span>
<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">LoginController</span> <span class="token punctuation">{</span>

    <span class="token comment" spellcheck="true">// ......</span>

    <span class="token annotation punctuation">@RequestMapping</span><span class="token punctuation">(</span>value <span class="token operator">=</span> <span class="token string">"/login"</span><span class="token punctuation">)</span>
    <span class="token annotation punctuation">@ResponseBody</span>
    <span class="token keyword">public</span> R <span class="token function">login</span><span class="token punctuation">(</span>User user<span class="token punctuation">)</span> <span class="token punctuation">{</span>
        <span class="token keyword">try</span> <span class="token punctuation">{</span>
            Subject<span class="token punctuation">.</span><span class="token function">login</span><span class="token punctuation">(</span>user<span class="token punctuation">.</span><span class="token function">getUsername</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>user<span class="token punctuation">.</span><span class="token function">getPassword</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">UserNameIsEmptyException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">UserNotFindException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">PasswordIsNotCorrectException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span>
            e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
        <span class="token punctuation">}</span>
        <span class="token keyword">return</span> R<span class="token punctuation">.</span><span class="token function">out</span><span class="token punctuation">(</span>RespCode<span class="token punctuation">.</span>Success<span class="token punctuation">,</span>null<span class="token punctuation">)</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
<span class="token punctuation">}</span></code></pre>
<h3 id="对于前端按钮的控制"><a href="#对于前端按钮的控制" class="headerlink" title="对于前端按钮的控制"></a>对于前端按钮的控制</h3><p>比如我想让有权限的人看得到这个按钮，没权限的人看不到</p>
<pre class=" language-html"><code class="language-html"><span class="token doctype">&lt;!DOCTYPE html></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>html</span> <span class="token attr-name">lang</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>en<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">xmlns:</span>th</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>http://www.thymeleaf.org<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>head</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>meta</span> <span class="token attr-name">charset</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>UTF-8<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>title</span><span class="token punctuation">></span></span>index<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>title</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>head</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>body</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name"><span class="token namespace">th:</span>href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@{/toLogin}<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>${#session.getAttribute(<span class="token punctuation">'</span>username<span class="token punctuation">'</span>) eq null}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>登录<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name"><span class="token namespace">th:</span>href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@{/user/toAddUser}<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>${#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>) ne null &amp;&amp; #lists.contains(#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>),<span class="token punctuation">'</span>user:add<span class="token punctuation">'</span>)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>添加用户<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name"><span class="token namespace">th:</span>href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@{/user/}<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>${#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>) ne null &amp;&amp; #lists.contains(#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>),<span class="token punctuation">'</span>user:delete<span class="token punctuation">'</span>)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>删除用户<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name"><span class="token namespace">th:</span>href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@{/user/}<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>${#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>) ne null &amp;&amp; #lists.contains(#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>),<span class="token punctuation">'</span>user:query<span class="token punctuation">'</span>)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>查看用户<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span> <span class="token attr-name"><span class="token namespace">th:</span>href</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>@{/user/}<span class="token punctuation">"</span></span> <span class="token attr-name"><span class="token namespace">th:</span>if</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>${#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>) ne null &amp;&amp; #lists.contains(#session.getAttribute(<span class="token punctuation">'</span>permissions<span class="token punctuation">'</span>),<span class="token punctuation">'</span>user:update<span class="token punctuation">'</span>)}<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>修改用户<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>body</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>html</span><span class="token punctuation">></span></span></code></pre>
<h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>本次练习，收获颇丰。但还有许多东西需要深入，像java8的list.stream().map()，aop的使用等等</p>
<p>练习RBAC的目的是为了上手框架，后续需要把springsecurity 和 shiro 整合到spring boot中</p>

  </article>

  
      
    <div class="nexmoe-post-copyright">
        <strong>本文作者：</strong>塔纳托斯<br>
        <strong>本文链接：</strong><a href="http://hai-chao.gitee.io/blog/2022/01/15/24.lian-xi-zhi-rbac-jian-dan-quan-xian/" title="http:&#x2F;&#x2F;hai-chao.gitee.io&#x2F;blog&#x2F;2022&#x2F;01&#x2F;15&#x2F;24.lian-xi-zhi-rbac-jian-dan-quan-xian&#x2F;" target="_blank" rel="noopener">http:&#x2F;&#x2F;hai-chao.gitee.io&#x2F;blog&#x2F;2022&#x2F;01&#x2F;15&#x2F;24.lian-xi-zhi-rbac-jian-dan-quan-xian&#x2F;</a><br>
        
            <strong>版权声明：</strong>本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/cn/deed.zh" target="_blank">CC BY-NC-SA 3.0 CN</a> 协议进行许可
        
    </div>


  
  
  <div class="nexmoe-post-meta nexmoe-rainbow">
    
    
        <a class="nexmoefont icon-tag-fill -none-link" href="/blog/tags/%E5%AD%A6%E4%B9%A0/" rel="tag">学习</a>
    
</div>

  
      <div class="nexmoe-post-footer">
          
      </div>
  
</div>
            <div class="nexmoe-post-right">
              <div class="nexmoe-fixed">
                  <div class="nexmoe-tool"> 
                    
                      
                        
                          
                          
                              <button class="mdui-fab catalog" style="overflow:unset;">
                                  <i class="nexmoefont icon-i-catalog"></i>
                                  <div class="nexmoe-toc">
                                      <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#%E8%A1%A8%E8%AE%BE%E8%AE%A1"><span class="toc-number">1.</span> <span class="toc-text">表设计</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BC%96%E7%A0%81"><span class="toc-number">2.</span> <span class="toc-text">编码</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%A1%B9%E7%9B%AE%E7%BB%93%E6%9E%84"><span class="toc-number">2.1.</span> <span class="toc-text">项目结构</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B0%81%E8%A3%85%E5%93%8D%E5%BA%94%E7%B1%BB"><span class="toc-number">2.2.</span> <span class="toc-text">封装响应类</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%A4%E8%AF%81"><span class="toc-number">2.3.</span> <span class="toc-text">认证</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8E%88%E6%9D%83"><span class="toc-number">2.4.</span> <span class="toc-text">授权</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E9%89%B4%E6%9D%83"><span class="toc-number">2.5.</span> <span class="toc-text">鉴权</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E6%8A%BD%E7%A6%BB%E8%AE%A4%E8%AF%81%E5%92%8C%E6%8E%88%E6%9D%83"><span class="toc-number">2.6.</span> <span class="toc-text">抽离认证和授权</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9E%E7%8E%B0Realm%E6%8E%A5%E5%8F%A3"><span class="toc-number">2.7.</span> <span class="toc-text">实现Realm接口</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AF%B9%E4%BA%8E%E5%89%8D%E7%AB%AF%E6%8C%89%E9%92%AE%E7%9A%84%E6%8E%A7%E5%88%B6"><span class="toc-number">2.8.</span> <span class="toc-text">对于前端按钮的控制</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#%E7%BB%93%E8%AF%AD"><span class="toc-number">3.</span> <span class="toc-text">结语</span></a></li></ol>
                                  </div>
                              </button>
                          
                          
                      
                    
                      <a href="#nexmoe-content" class="toc-link" aria-label="回到顶部" title="top"><button class="mdui-fab mdui-ripple"><i class="nexmoefont icon-caret-top"></i></button></a>
                  </div>
              </div>
            </div>
        </div>
    </div>
    
    <script src="https://cdn.jsdelivr.net/combine/npm/lazysizes@5.1.0/lazysizes.min.js,npm/mdui@0.4.3/dist/js/mdui.min.js?v=1"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>

 

<script async src="/blog/js/app.js?v=1679297521110"></script>



<script src="https://cdn.jsdelivr.net/npm/justifiedGallery@3.8.1/dist/js/jquery.justifiedGallery.min.js"></script>
<script>
	$(".justified-gallery").justifiedGallery({
		rowHeight: 160,
		margins: 10,
	});
</script>


    





</body>

</html>
